﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Media;
using System.Reflection;
using System.Text.RegularExpressions;
using Telerik.Windows.Controls;
using TruckScale.Helpers;
using TruckScale.Models;
using static TruckScale.Helpers.LogHelper;

namespace TruckScale.ViewModels
{
  public partial class MainViewModel
  {
    private string _weighTemplateName;

    /// <summary>
    /// WeighMode
    /// 1：显示一个称重按钮，一次称重时用
    /// 2：显示第一次称重、第二次称重，自动判断毛重皮重
    /// 3：显示毛重称重、皮重称重，不自动判断毛重皮重
    /// 4: 智能称重(有皮重一次称重，无皮重两次称重)
    /// </summary>
    public int WeighMode { get; set; }
    public bool ShowSwitchWeighTemplate { get; set; }
    public bool ShowPrintButton { get; set; }
    public string WeighTemplateName
    {
      get => _weighTemplateName;
      set
      {
        _weighTemplateName = value;
        Global._weighConfig["WeighTemplateName"] = value;
        WeighConfigModel.UpdateConfig("WeighTemplateName", value);
        SetLog((value == "Sale") ? "切换为销售磅单" : "切换为采购磅单", LogType.OperationLogger);
      }
    }
    public DelegateCommand OnceWeighCommand { get; set; }
    public DelegateCommand FirstWeighCommand { get; set; }
    public DelegateCommand SecondWeighCommand { get; set; }
    public DelegateCommand GrossWeighCommand { get; set; }
    public DelegateCommand TareWeighCommand { get; set; }
    public DelegateCommand AutoWeighCommand { get; set; }
    public DelegateCommand PrintCommand { get; set; }

    private void InitWeighModeProps()
    {
      WeighMode = Convert.ToInt32(Global._weighConfig["WeighMode"]);
      ShowSwitchWeighTemplate = Convert.ToBoolean(Global._weighConfig["ShowSwitchWeighTemplate"]);
      ShowPrintButton = Convert.ToBoolean(Global._weighConfig["ShowPrintButton"]);
    }

    private void InitWeighModeCommands()
    {
      OnceWeighCommand = new DelegateCommand(OnOnceWeighExecuted, OnCanOnceWeighExecuted);
      FirstWeighCommand = new DelegateCommand(OnFirstWeighExecuted, OnCanFirstWeighExecuted);
      SecondWeighCommand = new DelegateCommand(OnSecondWeighExecuted, OnCanSecondWeighExecuted);
      GrossWeighCommand = new DelegateCommand(OnGrossWeighExecuted, OnCanGrossWeighExecuted);
      TareWeighCommand = new DelegateCommand(OnTareWeighExecuted, OnCanTareWeighExecuted);
      AutoWeighCommand = new DelegateCommand(OnAutoWeighExecuted, OnCanAutoWeighExecuted);
      PrintCommand = new DelegateCommand(OnPrintExecuted, OnCanPrintExecuted);
    }

    private bool OnCanOnceWeighExecuted(object obj)
    {
      return true;
    }
    private void OnOnceWeighExecuted(object obj)
    {
      CarModel car = CarModel.SelectCarByPlateNo(WeighRecord.Ch);

      int bh = WeighRecordModel.SelectBh(DateTime.Today.ToString("yyyyMMdd")) + 1;
      WeighRecord.Bh = DateTime.Today.ToString("yyyyMMdd") + bh.ToString("0000");
      if (Convert.ToBoolean(Global._weighConfig["HasBhPrefix"]))
      {
        WeighRecord.Bh = Global._weighConfig["BhPrefix"] + WeighRecord.Bh;
      }
      WeighRecord.Mz = WeighStr;
      WeighRecord.Mzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      WeighRecord.Mzsby = Global._currentUser.UserId;
      WeighRecord.Pz = string.IsNullOrEmpty(car.VehicleWeight) ? "0" : car.VehicleWeight;
      WeighRecord.Pzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      WeighRecord.Pzsby = Global._currentUser.UserId;
      WeighRecord.Jz = Math.Abs(Convert.ToDecimal(WeighRecord.Mz) - Convert.ToDecimal(WeighRecord.Pz)).ToString();
      WeighRecord.Jzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      WeighRecord.Weighbridge1 = Global._weighConfig["WeighBridgeName"];
      WeighRecord.WeighTemplate = Global._weighConfig["WeighTemplateName"];
      WeighRecord.WeighCount = 1;
      WeighRecord.IsFinish = true;

      WeighRecordModel.InsertRecord(WeighRecord);
      InitWeighFormProps();
      InitWeighRecordProps();
    }
    private bool OnCanFirstWeighExecuted(object obj)
    {
      if (Convert.ToDecimal(WeighStr) < Convert.ToDecimal(Global._weighConfig["MinWeight"]))
      {
        return false;
      }
      if (!IsSPConnected)
      {
        return false;
      }
      if (WeighRecord.Ch == null)
      {
        return false;
      }
      if (WeighRecord.WeighCount != 0)
      {
        return false;
      }
      if (weighingStatus == WeighingStatus.Completed)
      {
        return false;
      }
      return true;
    }
    private async void OnFirstWeighExecuted(object obj)
    {
      if (string.IsNullOrEmpty(WeighRecord.Ch))
      {
        SystemSounds.Beep.Play();
        SetLog("车牌号不能为空", LogType.OperationLogger);
        return;
      }
      int bh = WeighRecordModel.SelectBh(DateTime.Today.ToString("yyyyMMdd")) + 1;
      WeighRecord.Bh = DateTime.Today.ToString("yyyyMMdd") + bh.ToString("0000");
      if (Convert.ToBoolean(Global._weighConfig["HasBhPrefix"]))
      {
        WeighRecord.Bh = Global._weighConfig["BhPrefix"] + WeighRecord.Bh;
      }
      WeighRecord.Mz = WeighStr;
      WeighRecord.Mzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      WeighRecord.Mzsby = Global._currentUser.UserId;
      WeighRecord.Weighbridge1 = Global._weighConfig["WeighBridgeName"];
      WeighRecord.WeighTemplate = Global._weighConfig["WeighTemplateName"];
      WeighRecord.WeighCount = 1;
      WeighRecord.IsFinish = false;

      //备用字段公式计算
      //1. 查数据库看哪个字段有公式
      var smList = SpareModel.SelectSpareField();
      //2. 调用公式计算
      var properties = typeof(WeighRecordModel).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                             .Where(p => p.Name.StartsWith("By")).ToDictionary(p => p.Name, p => p);
      foreach (var spare in smList)
      {
        if (properties.TryGetValue(spare.SpareKey.Substring(1), out var property))
        {
          if (property != null && property.CanWrite)
          {
            property.SetValue(WeighRecord, FleeHelper.FormulaCalc(WeighRecord, spare.SpareValue));
          }
        }
      }

      WeighRecordModel.InsertRecord(WeighRecord);
      InitWeighFormProps();
      InitWeighRecordProps();
      Directory.CreateDirectory("./Snap/" + WeighRecord.Bh);
      Snap("FirstWeighing", WeighRecord.Bh);
      try
      {
        // 检查车牌相机图片是否存在
        string platePicPath = Path.Combine(Environment.CurrentDirectory, "Snap", "Temp", WeighRecord.Ch + ".jpg");
        string snapPath = Path.Combine(Environment.CurrentDirectory, "Snap", WeighRecord.Bh, "LPR1.jpg");
        if (File.Exists(platePicPath))
        {
          File.Move(platePicPath, snapPath);
        }
      }
      catch { }

      if (Convert.ToBoolean(Global._weighConfig["TTS1Enable"]))
      {
        TTSHelper.TTS(WeighRecord, Global._weighConfig["TTS1Text"]);
      }

      if (Convert.ToBoolean(Global._weighConfig["UploadEnable"]))
      {
        var jsonDict = new Dictionary<string, string>();
        foreach (var f in WeighFormField)
        {
          string fieldKey = Regex.Replace(f.WeighFormKey.Substring(1), "^[a-z]", m => m.Value.ToUpper());
          string fieldValue = WeighRecord.GetType().GetProperty(fieldKey).GetValue(WeighRecord)?.ToString();
          if (!string.IsNullOrEmpty(fieldValue))
          {
            jsonDict.Add(f.WeighFormValue, fieldValue);
          }
        }
        try
        {
          await HttpClientHelper.UploadWeighData(WeighRecord.Bh, JsonConvert.SerializeObject(jsonDict, Formatting.None));
        }
        catch (Exception e)
        {
          LogHelper.SetLog(e.Message, LogType.UploadLogger, LogLevel.Error);
        }        
      }

      weighingStatus = WeighingStatus.Completed;
      CheckBtnEnable();
    }
    private bool OnCanSecondWeighExecuted(object obj)
    {
      if (Convert.ToDecimal(WeighStr) < Convert.ToDecimal(Global._weighConfig["MinWeight"]))
      {
        return false;
      }
      if (!IsSPConnected)
      {
        return false;
      }
      if (WeighRecord.Ch == null)
      {
        return false;
      }
      if (WeighRecord.WeighCount != 1)
      {
        return false;
      }
      if (weighingStatus == WeighingStatus.Completed)
      {
        return false;
      }
      return true;
    }
    private async void OnSecondWeighExecuted(object obj)
    {
      try
      {
        if (Convert.ToDecimal(WeighRecord.Mz) > Convert.ToDecimal(WeighStr))
        {
          WeighRecord.Pz = WeighStr;
          WeighRecord.Pzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
          WeighRecord.Pzsby = Global._currentUser.UserId;
        }
        else
        {
          WeighRecord.Pz = WeighRecord.Mz;
          WeighRecord.Pzsj = WeighRecord.Mzsj;
          WeighRecord.Pzsby = WeighRecord.Mzsby;
          WeighRecord.Mz = WeighStr;
          WeighRecord.Mzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
          WeighRecord.Mzsby = Global._currentUser.UserId;
        }
      }
      catch (Exception)
      {
      }

      WeighRecord.Jz = Math.Abs(Convert.ToDecimal(WeighRecord.Mz) - Convert.ToDecimal(WeighRecord.Pz)).ToString();
      WeighRecord.Jzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

      WeighRecord.Weighbridge2 = Global._weighConfig["WeighBridgeName"];
      WeighRecord.WeighTemplate = Global._weighConfig["WeighTemplateName"];
      WeighRecord.WeighCount = 2;
      WeighRecord.IsFinish = true;


      //备用字段公式计算
      //1. 查数据库看哪个字段有公式
      var smList = SpareModel.SelectSpareField();
      //2. 调用公式计算
      var properties = typeof(WeighRecordModel).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                             .Where(p => p.Name.StartsWith("By")).ToDictionary(p => p.Name.ToLower(), p => p);
      foreach (var spare in smList)
      {
        if (properties.TryGetValue(spare.SpareKey.Substring(1), out var property))
        {
          if (property != null && property.CanWrite)
          {
            property.SetValue(WeighRecord, FleeHelper.FormulaCalc(WeighRecord, spare.SpareValue.Substring(1)));
          }
        }
      }

      WeighRecordModel.UpdateRecord(WeighRecord);
      InitWeighFormProps();
      InitWeighRecordProps();

      //抓拍图片
      Directory.CreateDirectory("./Snap/" + WeighRecord.Bh);
      Snap("SecondWeighing", WeighRecord.Bh);
      try
      {
        // 检查车牌相机图片是否存在
        string platePicPath = Path.Combine(Environment.CurrentDirectory, "Snap", "Temp", WeighRecord.Ch + ".jpg");
        string snapPath = Path.Combine(Environment.CurrentDirectory, "Snap", WeighRecord.Bh, "LPR2.jpg");
        if (File.Exists(platePicPath))
        {
          File.Move(platePicPath, snapPath);
        }
      }
      catch { }

      if (Convert.ToBoolean(Global._weighConfig["TTS2Enable"]))
      {
        TTSHelper.TTS(WeighRecord, Global._weighConfig["TTS2Text"]);
      }

      if (Convert.ToBoolean(Global._weighConfig["UploadEnable"]))
      {
        var jsonDict = new Dictionary<string, string>();
        foreach (var f in WeighFormField)
        {
          string fieldKey = Regex.Replace(f.WeighFormKey.Substring(1), "^[a-z]", m => m.Value.ToUpper());
          string fieldValue = WeighRecord.GetType().GetProperty(fieldKey).GetValue(WeighRecord)?.ToString();
          if (!string.IsNullOrEmpty(fieldValue))
          {
            jsonDict.Add(f.WeighFormValue, fieldValue);
          }
        }
        try
        {
          await HttpClientHelper.UploadWeighData(WeighRecord.Bh, JsonConvert.SerializeObject(jsonDict, Formatting.None));
        }
        catch (Exception e)
        {
          LogHelper.SetLog(e.Message, LogType.UploadLogger, LogLevel.Error);
        }
      }

      weighingStatus = WeighingStatus.Completed;
      CheckBtnEnable();
    }
    private bool OnCanGrossWeighExecuted(object obj)
    {
      return true;
    }
    private void OnGrossWeighExecuted(object obj)
    {

    }
    private bool OnCanTareWeighExecuted(object obj)
    {
      return true;
    }
    private void OnTareWeighExecuted(object obj)
    {

    }
    private bool OnCanAutoWeighExecuted(object obj)
    {
      return true;
    }
    private void OnAutoWeighExecuted(object obj)
    {
      //拿到车牌号后先查询此车是否有未完成的称重记录

      CarModel car = CarModel.SelectCarByPlateNo(WeighRecord.Ch);

      int bh = WeighRecordModel.SelectBh(DateTime.Today.ToString("yyyyMMdd")) + 1;
      WeighRecord.Bh = DateTime.Today.ToString("yyyyMMdd") + bh.ToString("0000");
      if (Convert.ToBoolean(Global._weighConfig["HasBhPrefix"]))
      {
        WeighRecord.Bh = Global._weighConfig["BhPrefix"] + WeighRecord.Bh;
      }
      WeighRecord.Mz = WeighStr;
      WeighRecord.Mzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
      WeighRecord.Mzsby = Global._currentUser.UserId;

      if (string.IsNullOrEmpty(car.VehicleWeight)) //需要第二次称重
      {

      }
      else //一次就称重完成
      {
        WeighRecord.Pz = string.IsNullOrEmpty(car.VehicleWeight) ? "0" : car.VehicleWeight;
        WeighRecord.Pzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        WeighRecord.Pzsby = Global._currentUser.UserId;
        WeighRecord.Jz = Math.Abs(Convert.ToDecimal(WeighRecord.Mz) - Convert.ToDecimal(WeighRecord.Pz)).ToString();
        WeighRecord.Jzsj = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        WeighRecord.Weighbridge1 = Global._weighConfig["WeighBridgeName"];
        WeighRecord.WeighTemplate = Global._weighConfig["WeighTemplateName"];
        WeighRecord.WeighCount = 1;
        WeighRecord.IsFinish = true;
      }
    }
    private bool OnCanPrintExecuted(object obj)
    {
      return true;
    }
    private void OnPrintExecuted(object obj)
    {
      //打印磅单功能
      PrinterHelper.PrintImg(WeighRecord, Global._weighConfig["WeighTemplateName"], PrinterHelper.PrintMode.Hand);
    }


  }
}
